.Dd July 3, 2017
.Dt GITSH_COMPLETIONS 5
.Os
.Sh NAME
.Nm gitsh_completions
.Nd Defines options for tab completion
.
.Sh DESCRIPTION
.Nm gitsh_completions
files define the tab completions options that are available in interactive
.Xr gitsh 1
sessions.
.Pp
The content of a
.Nm gitsh_completions
file consists of rules defining the options and arguments that are expected
by various commands.
.Xr gitsh 1
uses the rules to match the input before the word being completed
and to generate completions that are relevant in the context.
.Pp
Each rule is separated from other rules by a blank line.
.Pp
The first line of a rule specifies the name of the command
and the arguments it accepts. In the simplest case, these are just
space-separated words. For example, the following
.Nm gitsh_completions
file defines three rules for the
.Xr git-stash 1
command:
.Bd -literal -offset -indent
stash list

stash show

stash drop
.Ed
.Pp
With these rules in place,
.Xr gitsh 1
could tab complete the command
.Ic stash ,
or if the user had already entered
.Ic stash
it could tab complete the sub-commands
.Ic list ,
.Ic show ,
and
.Ic drop .
.Pp
In addition to literal words we expect to see in the command,
we can use variables that represent particular types of argument.
For example, the
.Xr git-add 1
command expects a file path as an argument:
.Bd -literal -offset -indent
add $path
.Ed
.Pp
See the section on
.Sx VARIABLES
for a complete list of what's supported.
.Pp
Some arguments are optional, and others can be repeated.
This can be specified using operators similar to those provided by
regular expressions. To expand the previous example,
.Xr git-add 1
can accept one or more paths preceded by an optional
.Ic "--"
token:
.Bd -literal -offset -indent
add --? $path+
.Ed
.Pp
In this example, the
.Ic ?
and
.Ic +
operators modify the meaning of the literal and variable arguments.
See the section on
.Sx OPERATORS
for a complete list of what's supported.
.Pp
Subsequent lines of each rule specify the options that the command accepts.
These lines start with a whitespace indent,
followed by the option name which must start with a
.Ic -
character,
optionally followed by an argument the option takes.
.Pp
The special
.Ic $opt
variable is used in the first line of the rule to specify where the options are
expected to appear. For example,
.Xr git-add 1
accepts options like
.Ic --all
and
.Ic --edit :
.Bd -literal -offset -indent
add $opt* --? $path+
  --all
  --edit
.Ed
.Pp
Some options are followed by an argument. This argument is specified in the
same way as a positional argument would be specified in the first line of the
completion rule, including support for the same variables and operators
(with the exception of the
.Ic $opt
variable).
For example, the
.Xr git-init 1
command can be passed a template directory via the
.Ic --template
option:
.Bd -literal -offset -indent
init $opt*
  --template $path
.Ed
.Pp
It is usually not useful to list short options (i.e. single character options)
in a completion rule, except when they expect an argument. For example, the
.Xr git-commit 1
command can be passed a file containing the commit message via the
.Ic -F
option:
.Bd -literal -offset -indent
commit $opt*
  -F $path
.Ed
.
.Sh ALIASES
Aliases for Git commands are expanded before applying tab completion rules,
allowing users to benefit from the standard completion rules even when they
are using an alias.
.Pp
Aliases for shell commands, i.e. aliases whose command begins with the
.Ic !
character, are not expanded, allowing users to define custom completion
rules.
.
.Sh FALLBACKS
The
.Ic fallback::
modifier can be used before a variable to indicate that it should only
be used if no other rule applies. This allows for the specification of
generic rules that will only be applied if no other, more specific rule
is available.
.Pp
To illustrate how this is useful, consider the following rules:
.Bd -literal -offset -indent
add $path+

$command ($path|$revision|$remote)
.Ed
.Pp
A user trying to tab complete arguments to
.Xr git-add 1
will match both rules: the input will match the
.Ic add
rule, and correctly be offered paths to complete, but will also match the
.Ic $command
rule, and so they will also be offered revisions and remotes.
.Pp
We can solve the problem by modifying the more generic rule to act as a
fallback:
.Bd -literal -offset -indent
add $path+

fallback::$command ($path|$revision|$remote)
.Ed
.Pp
Now we get the best of both worlds: tab completing arguments for
.Xr git-add 1
will match the specific rule and only be offered paths, but any other
command will use the fallback rule and be given a generic set of completions
including paths, revisions, and remotes.
.
.Sh OPERATORS
The following operators are supported. They have similar semantics to regular
expressions, except that they operate on an entire word instead of a single
character.
.Bl -tag -width Ds
.It Ic word?
Indicates that
.Ic word
can appear zero or one times. In other words,
.Ic word
is optional.
.It Ic word*
Indicates that
.Ic word
can appear zero or more times. In other words,
.Ic word
is optional and can be repeated.
.It Ic word+
Indicates that
.Ic word
can appear one or more times. In other words,
.Ic word
is required but can be repeated.
.It Ic (first|second)
Indicates that either
.Ic first
or
.Ic second
may appear. Unlike regular expressions, the surrounding parentheses are
required, and this is the only context in which parentheses may be used.
.El
.Pp
The various post-fix operators may be applied to a list of options, but the
options inside the list must be literals or variables. For example, various
commands take a
.Ic --recurse-submodules
option with an optional argument:
.Bd -literal -offset -indent
fetch $opt*
  --recurse-submodules (yes|on-demand|no)?
.Ed
.
.Sh VARIABLES
Variables represent types of arguments that we want to tab complete in a
.Xr gitsh 1
session.
.Pp
Variables are more permissive when they are matching the context before a
completion than when they are generating completions. For example, consider
the following rule:
.Bd -literal -offset -indent
diff $revision? $path
.Ed
.Pp
If the user enters
.Ic diff ,
followed by a space, and presses the tab key, then the
.Ic $revision
variable will produce the names of revisions in the repository as possible
completions.
However, if the user enters
.Ic diff my-branch ,
followed by a space, and presses the tab key, then the
.Ic $revision
variable will match the input
.Ic my-branch
regardless of whether or not it's a valid revision name.
.Xr gitsh 1
will assume the revision argument has been provided, and present completions
for the
.Ic $path
variable.
.Pp
The role of the tab completion system is to understand the structure of
commands and present useful options; it can leave the validation of the user's
input to Git.
.Pp
The following variables are supported:
.Bl -tag -width Ds
.It Ic $anything
Produces no completion options, but matches any user input. This is useful
for situations where we know Git requires an argument, but we're unable to
produce useful completions for it.
.It Ic $branch
Produces the names of Git branches in the repository. Note that the more
permissive
.Ic $revision
variable could be more appropriate in some situations.
.It Ic $command
Produces the names of Git commands. This includes any custom Git commands found
on the user's
.Ev PATH ,
the user's Git aliases, and internal gitsh commands.
.It Ic $path
Produces paths to files and directories, relative to the current working
directory.
.It Ic $remote
Produces the names of Git remotes in the current repository.
.It Ic $revision
Produces various names for Git revisions, including the names of local
branches, remote tracking branches, and tags.
.Pp
The completion options produced by this variable will also try to take
punctuation into account. For example, if the word being completed is
.Ic master..my-f ,
and there is a local branch called
.Ic my-feature ,
then the completions would include
.Ic master..my-feature .
.Pp
Note that the more specific
.Ic $branch
or
.Ic $tag
variables could be more appropriate in some situations.
.It Ic $opt
Produces the options specified on subsequent lines of the current rule.
See the
.Sx DESCRIPTION
section above for more details.
.Pp
Unlike other variables listed here,
.Ic $opt
only matches input that begins with a
.Ic -
character and is followed by one or more other characters.
For example,
.Ic -a
and
.Ic --all
would match, but
.Ic example.txt
and
.Ic --
wouldn't.
.It Ic $tag
Produces the names of Git tags in the repository. Note that the more
permissive
.Ic $revision
variable could be more appropriate in some situations.
.El
.
.Sh MODIFIERS
The meaning of variables can be modified by adding a prefix.
.Pp
The following modifiers are supported:
.Bl -tag -width Ds
.It Ic fallback::
Indicates that the variable should only be matched if no other rule is
available. See the
.Sx FALLBACKS
section above for more details.
.El
.
.Sh FILES
.Bl -tag -width Ds
.It Pa @pkgsysconfdir@/completions
System-wide tab completions file, which defines the tab completion options
for popular Git commands.
.It Pa $HOME/.gitsh_completions
User-defined completions file, which can be used to add completions for custom
commands or aliases.
.El
.
.Sh EXAMPLES
The
.Xr git-add 1
command takes zero or more options,
followed by an optional
.Ic -- ,
followed by one or more file system paths.
.Pp
This argument scheme is represented as:
.Bd -literal -offset -indent
add $opt* --? $path+
  --all
  --edit
  --force
  --update
.Ed
.Pp
I have a custom command called
.Ic git browse ,
which takes two arguments: an optional Git revision, followed by a single
file system path.
.Pp
I can add this to my
.Ic gitsh_completions
file as:
.Bd -literal -offset -indent
browse $revision? $path
.Ed
.
.Sh SEE ALSO
.Xr gitsh 1
.
.Sh AUTHORS
.An George Brocklehurst Aq george@thoughtbot.com
.An thoughtbot Aq hello@thoughtbot.com
